from database.neo4j import get_neo4j_connection
from models.node import Node, NodeRelation, NodeWithRelations

class Neo4jService:
    def __init__(self):
        self.neo4j_conn = get_neo4j_connection()

    def search_nodes_by_string(self, search_string: str) -> list:
        """根据字符串搜索节点"""
        query = """
        MATCH (n)
        WHERE toLower(n.name) CONTAINS toLower($search_string) OR 
              toLower(n.description) CONTAINS toLower($search_string)
        RETURN n LIMIT 50
        """
        parameters = {"search_string": search_string}
        results = self.neo4j_conn.query(query, parameters)
        
        nodes = []
        for record in results:
            node = record["n"]
            nodes.append({
                "id": node.element_id,
                "labels": list(node.labels),
                "properties": dict(node)
            })
        return nodes

    def get_node_with_relations(self, node_id: str) -> dict:
        """获取节点及其上下游关系"""
        # 查询节点本身
        node_query = """
        MATCH (n) WHERE elementId(n) = $node_id
        RETURN n
        """
        node_result = self.neo4j_conn.query(node_query, {"node_id": node_id})
        if not node_result:
            return None
        
        node = node_result[0]["n"]
        node_data = {
            "id": node.element_id,
            "labels": list(node.labels),
            "properties": dict(node)
        }
        
        # 查询入边关系
        incoming_query = """
        MATCH (s)-[r]->(n) WHERE elementId(n) = $node_id
        RETURN s, r
        """
        incoming_results = self.neo4j_conn.query(incoming_query, {"node_id": node_id})
        incoming_relations = []
        for record in incoming_results:
            source = record["s"]
            rel = record["r"]
            incoming_relations.append({
                "source": {
                    "id": source.element_id,
                    "labels": list(source.labels),
                    "properties": dict(source)
                },
                "target": node_data,
                "type": rel.type,
                "properties": dict(rel)
            })
        
        # 查询出边关系
        outgoing_query = """
        MATCH (n)-[r]->(t) WHERE elementId(n) = $node_id
        RETURN t, r
        """
        outgoing_results = self.neo4j_conn.query(outgoing_query, {"node_id": node_id})
        outgoing_relations = []
        for record in outgoing_results:
            target = record["t"]
            rel = record["r"]
            outgoing_relations.append({
                "source": node_data,
                "target": {
                    "id": target.element_id,
                    "labels": list(target.labels),
                    "properties": dict(target)
                },
                "type": rel.type,
                "properties": dict(rel)
            })
        
        return {
            "node": node_data,
            "incoming_relations": incoming_relations,
            "outgoing_relations": outgoing_relations
        }

    def update_node_properties(self, node_id: str, properties: dict) -> bool:
        """更新节点属性"""
        # 构建更新属性的查询
        set_clauses = []
        params = {"node_id": node_id}
        
        for key, value in properties.items():
            param_name = f"prop_{key}"
            set_clauses.append(f"n.{key} = ${param_name}")
            params[param_name] = value
        
        if not set_clauses:
            return True  # 没有属性需要更新
        
        query = f"""
        MATCH (n) WHERE elementId(n) = $node_id
        SET {', '.join(set_clauses)}
        RETURN n
        """
        
        try:
            result = self.neo4j_conn.query(query, params)
            return len(result) > 0
        except Exception as e:
            print(f"Failed to update node: {e}")
            return False

# 创建服务实例
eo4j_service = Neo4jService()

def get_neo4j_service():
    return neo4j_service